﻿#ifndef __IAnimation_H__
#define __IAnimation_H__

#include <lampe/config.h>
#include <ISkinnedMesh.h>
#include <IAnimatedMeshSceneNode.h>
#include <lampe/IReferenceCounted.h>
#include <boost/filesystem.hpp>
#include <lampe/types.h>

namespace lampe{
namespace animation{

class IAnimationRecord;

/***
 * @class IAnimation
 * Хранит в себе информацию о группе анимаций. Пример: группа анимаций это
 * все анимации пренадлежащие одной рассе и полу
 *
 * Пример:
 * irr::scene::IAnimatedMeshSceneNode*node;
 * node=****;//создаём узел, указываем модель и т.д.
 * IAnimation*elf_amination=SceneManager->createSkinnedAnimation("elf");//создаём анимационную группу
 * elf_amination->addAnimationFromFile("run.x","run");//добовляем анимацию "run" из файла run.x
 * elf_amination->useAnimation(node);//устанавливаем костной модели анимационные данные из elf_amination.
 * elf_amination->useFor("run",node);//применяем анимацию run для модели
 */
class IAnimation:public virtual lampe::IReferenceCounted{
public:
	/***
	 * Возвращяет имя группы анимаций
	 *
	 * @return имя группы анимаций
	 */
    virtual lampe::String getName()=0;

	/***
	 * Устанавливает новое имя
	 *
	 * @param name новое имя
	 */
    virtual void setName(lampe::String name)=0;

	/***
	 * Находит анимацию по её имяни
	 *
	 * @param name имя анимации, которую нужно найти
	 * @return номер анимации. Если анимация не найдена, то вернёт -1
	 */
    virtual irr::s32 indexOf(lampe::String name)=0;
	
	/***
	* Возвращяет номер записи по её указателю
	*
	* @param animation Анимация, которую нужно найти
	* @return номер указанной анимации в списке. Если не найдена, то вернёт -1
	* */
	virtual irr::s32 indexOfRecord(IAnimationRecord*animation)=0;

	/***
	 * Возвращяет анимацию по её номеру
	 *
	 * @param index номер анимации
	 * @return анимация. Если анимация не найдена, то верёт null
	 */
	virtual IAnimationRecord*getAnimationByIndex(irr::u32 index)=0;

	/***
	 * Находит и возвращяет анимацию по её имини. Если не найдена, то вернёт NULL
	 *
	 * @param name название анимции
	 * @return анимация, имеющее указанное имя. Если анимация с указанным имянем не найдена, то вернёт NULL
	 */
    virtual IAnimationRecord*getAnimationByName(lampe::String name)=0;

	/***
	 * Возвращяет созданы ли уже кости
	 *
	 * @return TRUE если кости созданы, иначе FALSE
	 */
	virtual bool getNeedCreateBone()=0;

	/***
	 * Возвращяет меш, в котором хранится супер-анимация
	 *
	 * @return итоговая супер-анимация
	 */
	virtual irr::scene::ISkinnedMesh*getMesh()=0;

	/***
	 * Добавляет анимацию из меша в группу анимаций
	 *
	 * @param a меш анимации
	 * @param name имя меша
	 * */
    virtual IAnimationRecord*addAnimationFromMesh(irr::scene::ISkinnedMesh*a,lampe::String name)=0;
	
	/***
	* Добовляет анимацию из файла в группу анимаций
	*
	* @param filename путь к файлу с анимацией
	* @param name название анимации (то как оно будет хранится в группе анимаций)
	* */
    virtual IAnimationRecord*addAnimationFromFile(boost::filesystem::path,lampe::String name)=0;

	/***
	 * Применяет анимацию к моделе
	 *
	 * @param name имя анимации (например run)
	 * @param node узел-модель к которой нужно применить анимацию
	 */
    virtual void useFor(lampe::String name,irr::scene::IAnimatedMeshSceneNode*node)=0;

	/***
	* Устанавливает модели источник анимации на текущий. т.е. фактический заставляет модель проигрывать
	* именно текущую группу анимаций. Перед началом вызовов useFor(...) обязательно нужно вызвать этот метод,
	* иначе вызов useFor(...) никчиму не приведёт.
	*
	* @param node узел, которому нужно устанавить анимационную группу
	* */
	virtual void useAnimation(irr::scene::IAnimatedMeshSceneNode*node)=0;
};

IAnimation*createSkinnedAnimation(lampe::String name,irr::scene::ISceneManager*manager);

}//namespace animation
}//namespace irr

#endif
